/** BrownianPanel.java
 * 
 * Provides a visualization panel for Geometric Series.
 *
 * Author: Ralph Gootee <rgootee@gmail.com> 
 * Copyright (c) 2007-2008
 * GNU License
 *
 **/

import java.util.*; 

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

//------------------------------------------------------------------------------
class BrownianPanel extends JPanel implements ComponentListener{
 
 	private int N;
 	private int tickLength;
 	private int t;
 	
 	/* off screen buffer */
 	private Image image;
 	
	private int [] movement;
 
 	//--------------------------------------------------------------------------
	BrownianPanel(int n){
		
		// for resize events 
		addComponentListener(this);		
		
		N = n;
		t = n;
		
		tickLength = 1;

		constructMovement();
		constructImage(); // this will probably just be ignored
	}
	
	//--------------------------------------------------------------------------
	public void paint( Graphics gold ) {
  		gold.drawImage(image,0,0,Color.black,this);
 	}
 	
 	//--------------------------------------------------------------------------
 	private void constructImage(){
	
		int w = getSize().width;
		int h = getSize().height;
	
		if(w == 0 || h == 0) return;
	
		// Make sure the image is compatible with the screen
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
  	  	GraphicsDevice gs = ge.getDefaultScreenDevice();
    	GraphicsConfiguration gc = gs.getDefaultConfiguration();

		// Create an image that does not support transparency
    	image = gc.createCompatibleImage(w, h, Transparency.BITMASK);
		
		Graphics gold = image.getGraphics();
 		
 		Graphics2D g = (Graphics2D)gold;
 	
 		
 	
 		paintBackground(g);
 	
		// we want the origin to be at (0,0)
		g.translate(getSize().width/2,getSize().height/2);
		
		int lastX =0;
		int lastY =0;
		
		g.setColor(Color.red);
 	
 		for(int i=0;i<t;i++){
			
			if(movement[i] == 0){
				g.drawLine(lastX,lastY,lastX,lastY+tickLength);
				lastY += tickLength;
			}else if(movement[i] == 1){
				g.drawLine(lastX,lastY,lastX+tickLength,lastY);
				lastX += tickLength;
			}else if(movement[i] == 2){
				g.drawLine(lastX,lastY,lastX,lastY-tickLength);
				lastY -= tickLength;
			}else if(movement[i] == 3){
				g.drawLine(lastX,lastY,lastX-tickLength,lastY);
				lastX -= tickLength;
			}
		}
 		
 		g.translate(-getSize().width/2,-getSize().height/2);
		paintForeground(g);
 	
 	}
 	
 	//--------------------------------------------------------------------------
 	private void paintForeground(Graphics2D g){
 	
 		int hudHeight = 20;
 		int hudTopPadding = 15;
 		
 		Color textColor = Color.white;
 		
 		g.setColor(new Color(50,50,50));
 		
 		g.fillRect(0,0,getSize().width,hudHeight);
 		
 		g.setColor(textColor);
 		g.drawString("t: " + t ,10,hudTopPadding);	
 	}
 	
 	//--------------------------------------------------------------------------
	private void paintBackground(Graphics2D g){
		
		int w = getSize().width;
		int h = getSize().height;
		
		// bg color
		g.setColor(Color.black);
		g.fillRect(0,0,w,h);
		
		// axes
		Color axesColor = new Color(50,50,50);
		g.setColor(axesColor);
		
		g.drawLine(0,h/2,w,h/2);
		g.drawLine(w/2,0,w/2,h);
	
	}
 	
 	//--------------------------------------------------------------------------
 	public void setT(int t_){
 		t = t_;
 		
 		constructImage();
 		repaint();
 	}
 	
 	//--------------------------------------------------------------------------
	public void constructMovement(){
		
		Random generator = new Random();
		movement = new int[N];
	
		for(int i=0;i<N;i++){
			movement[i] = generator.nextInt(4); 
		}
	
	}
	
	//--------------------------------------------------------------------------
	public void reconstruct(){
		constructMovement();
		constructImage();
		repaint();
	}
	
	//--------------------------------------------------------------------------
    public void componentResized(ComponentEvent e) {
    	constructImage();
    	repaint();
    }
	
	//--------------------------------------------------------------------------
	public void componentHidden(ComponentEvent e) {}
    public void componentMoved(ComponentEvent e) {}
    public void componentShown(ComponentEvent e) {}

}